package com.example.itcacp.config;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.example.itcacp.entity.User;
import com.example.itcacp.repository.mybatis.UserMapper;
import com.example.itcacp.exception.CustomerException;
import jakarta.annotation.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Component
public class JWTInterceptor extends OncePerRequestFilter {

    private static final Logger logger = LoggerFactory.getLogger(JWTInterceptor.class);

    @Resource
    private UserMapper userMapper;

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
            throws ServletException, IOException {
        try {
            // 1. 从请求头获取 token
            String token = resolveToken(request);

            if (token != null) {
                // 2. 验证 JWT
                User user = validateToken(token);

                // 3. 创建并设置认证信息
                if (user != null) {
                    Authentication authentication = createAuthentication(user);
                    SecurityContextHolder.getContext().setAuthentication(authentication);
                }
            }
        } catch (CustomerException e) {
            // 处理认证异常
            response.sendError(Integer.parseInt(e.getCode()), e.getMessage());
            return;
        } catch (Exception e) {
            logger.error("JWT验证失败", e);
            response.sendError(HttpServletResponse.SC_UNAUTHORIZED, "认证失败");
            return;
        }

        // 继续过滤器链
        filterChain.doFilter(request, response);
    }

    private String resolveToken(HttpServletRequest request) {
        String bearerToken = request.getHeader("token");
        if (StringUtils.hasText(bearerToken)) {
            return bearerToken;
        }
        // 从参数中获取 token
        return request.getParameter("token");
    }

    private User validateToken(String token) throws CustomerException {
        try {
            // 验证签名
            Algorithm algorithm = Algorithm.HMAC256("1234567890-abcdefghijklmnopqrstuvwxyz");
            JWT.require(algorithm).build().verify(token);

            // 解析用户信息
            String audience = JWT.decode(token).getAudience().get(0);
            String[] split = audience.split("-");
            String userId = split[0];
            String roleName = split[1];

            // 从数据库加载用户
            User user = userMapper.findById(userId);
            if (user == null) {
                throw new CustomerException("401", "用户不存在");
            }

            return user;
        } catch (JWTVerificationException e) {
            throw new CustomerException("401", "无效的token");
        } catch (Exception e) {
            throw new CustomerException("401", "认证失败");
        }
    }

    private Authentication createAuthentication(User user) {
        List<GrantedAuthority> authorities = new ArrayList<>();
        authorities.add(new SimpleGrantedAuthority("ROLE_" + user.getRole().getRoleName()));

        return new UsernamePasswordAuthenticationToken(
                user.getUsername(),
                null,
                authorities
        );
    }
}









//package com.example.itcacp.config;
//
//import cn.hutool.core.util.StrUtil;
//import com.auth0.jwt.JWT;
//import com.auth0.jwt.JWTVerifier;
//import com.auth0.jwt.algorithms.Algorithm;
//import com.example.itcacp.entity.User;
//import com.example.itcacp.exception.CustomerException;
//import com.example.itcacp.repository.mybatis.UserMapper;
//import jakarta.annotation.Resource;
//import jakarta.servlet.http.HttpServletRequest;
//import jakarta.servlet.http.HttpServletResponse;
//import org.slf4j.Logger;
//import org.slf4j.LoggerFactory;
//import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
//import org.springframework.security.core.Authentication;
//import org.springframework.security.core.GrantedAuthority;
//import org.springframework.security.core.authority.SimpleGrantedAuthority;
//import org.springframework.security.core.context.SecurityContextHolder;
//import org.springframework.stereotype.Component;
//import org.springframework.web.servlet.HandlerInterceptor;
//
//import java.util.ArrayList;
//import java.util.List;
//
//
//@Component
//public class JWTInterceptor implements HandlerInterceptor {
//
//    private static final Logger logger = LoggerFactory.getLogger( JWTInterceptor.class);
//
//    @Resource
//    private UserMapper userMapper;
//
//    @Override
//    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//        // 1. 从请求头拿到token
//        String token = request.getHeader("token");
//        if (StrUtil.isEmpty(token)) {
//            // 如果没拿到，从参数里再拿一次
//            token = request.getParameter("token");
//        }
//        // 2. 认证token
//        if (StrUtil.isBlank(token)) {
//            throw new CustomerException ("401", "您无权限操作");
//        }
//        User account = null;  // 对应账户
//        StrUtil.isBlank(token);
//        try {
//            // 拿到token 的载荷数据
//            String audience = JWT.decode(token).getAudience().get(0);
//            String[] split = audience.split("-");
//            String user_id = split[0];
//            String rolename = split[1];
//            // 根据token解析出来的userId去对应的表查询用户信息
//            if ("ADMIN".equals(rolename)) {
//                account = userMapper.findById(user_id);
//            } else if ("USER".equals(rolename)) {
//                account = userMapper.findById(user_id);
//            }
//        } catch (Exception e) {
//            throw new CustomerException("401", "您无权限操作");
//        }
//        if (account == null) {
//            throw new CustomerException("401", "您无权限操作");
//        }
//        // 3. 验证签名
//        try {
//            // 1. 验证 JWT 签名（使用统一密钥）
//            Algorithm algorithm = Algorithm.HMAC256("1234567890-abcdefghijklmnopqrstuvwxyz");
//            JWTVerifier verifier = JWT.require(algorithm).build();
//            verifier.verify(token);
//        } catch (Exception e) {
//            throw new CustomerException("401", "签名错误,您无权限操作或登录已过期");
//        }
//
//        // 4. 创建 Spring Security 认证对象
//        List<GrantedAuthority> authorities = new ArrayList<> ();
//        authorities.add(new SimpleGrantedAuthority ("ROLE_" + account.getRole().getRoleName()));
//        Authentication authentication = new UsernamePasswordAuthenticationToken (
//                account.getUsername(),
//                null,
//                authorities
//        );
//        // 5. 设置认证信息到 SecurityContext
//        SecurityContextHolder.getContext().setAuthentication(authentication);
//
//        // 4. 认证成功
//        return true;
//    }
//}
